package com.autumn.sms.service.services.impl;

import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.autumn.application.dto.PageQueryResult;
import com.autumn.application.dto.input.DefaultPrimaryKeyInput;
import com.autumn.application.dto.input.PageQueryInput;
import com.autumn.application.dto.input.QueryCriteriaItemInput;
import com.autumn.mybatis.criterion.IQuerySection;
import com.autumn.mybatis.criterion.ISpecifyUpdateSection;
import com.autumn.mybatis.criterion.Query;
import com.autumn.mybatis.criterion.SpecifyUpdate;
import com.autumn.sms.service.consts.ServiceConsts;
import com.autumn.sms.service.entities.SmsAppInfo;
import com.autumn.sms.service.entities.SmsAppTemplate;
import com.autumn.sms.service.repositories.ISmsAppInfoRepository;
import com.autumn.sms.service.repositories.ISmsAppTemplatePlatformRepository;
import com.autumn.sms.service.repositories.ISmsAppTemplateRepository;
import com.autumn.sms.service.services.ICacheService;
import com.autumn.sms.service.services.IRemoteAppService;
import com.autumn.sms.service.services.ISmsAppInfoService;
import com.autumn.sms.service.services.dto.input.RemoteServiceInput;
import com.autumn.sms.service.services.dto.input.SmsAppInfoInput;
import com.autumn.sms.service.services.dto.input.SmsAppInfoUpdateInput;
import com.autumn.sms.service.services.dto.output.RemoteAppInfoOutput;
import com.autumn.sms.service.services.dto.output.SmsAppInfoOutput;
import com.autumn.sms.service.utils.AuditUtils;
import com.autumn.util.AutoMapUtils;
import com.autumn.util.DataRollbackException;
import com.autumn.validation.ValidationException;
import com.autumn.web.vo.ApiResponse;

/**
 * 短信应用信息服务
 * 
 * @author JuWa ▪ Zhang
 * @date 2018年1月13日
 * @since jdk 1.8
 */
@Service
public class SmsAppInfoServiceImpl extends AbstractBasicService<ISmsAppInfoRepository, SmsAppInfo>
		implements ISmsAppInfoService {

	@Autowired
	private ICacheService cacheService;

	@Autowired
	private ISmsAppInfoRepository appRepo;

	@Autowired
	private ISmsAppTemplateRepository appTemplateRepo;

	@Autowired
	private ISmsAppTemplatePlatformRepository appTemplatePlatformRepo;

	@Autowired
	private IRemoteAppService appService;

	@Override
	public SmsAppInfoOutput add(SmsAppInfoInput input) {
		// 远程检测该应用是否已注册
		ApiResponse<RemoteAppInfoOutput> response = appService.get(new RemoteServiceInput(input.getServiceId()));
		RemoteAppInfoOutput appinfo = response.getResult();
		if (appinfo == null) {
			throw new ValidationException("该应用未在配置中心注册");
		}
		Query query = new Query(SmsAppInfo.class);
		AuditUtils.filterDelete(query);
		query.eq("serviceId", input.getServiceId());
		SmsAppInfo first = appRepo.selectFirst(query.builderSection());
		if (first != null) {
			throw new ValidationException(String.format("serviceId为 [%s] 的应用记录已经存在", input.getServiceId()));
		}
		first = AutoMapUtils.mapTo(SmsAppInfo.class, input);
		first.insertAuditingInitialize();
		first.setServideName(appinfo.getAppName());
		// 设置serviceKey
		first.setServiceKey(UUID.randomUUID().toString().replaceAll("-", ""));
		// 新增应用设置为草稿状态
		first.setStatus(ServiceConsts.Status.STATUS_DRAFT);
		appRepo.insert(first);
		return AutoMapUtils.mapTo(SmsAppInfoOutput.class, first);
	}

	@Override
	public SmsAppInfoOutput modify(SmsAppInfoInput input) {
		SmsAppInfoUpdateInput updateInput = (SmsAppInfoUpdateInput) input;
		SmsAppInfo appInfo = checkIsExistEntityByPrimaryId(updateInput.getId());
		if (appInfo.getStatus() == ServiceConsts.Status.STATUS_RELEASE) {
			throw new ValidationException("发布状态的应用不能修改");
		}
		if (! input.getServiceId().equals( appInfo.getServiceId())) {
			// 远程检测该应用是否已注册
			ApiResponse<RemoteAppInfoOutput> response = appService
					.get(new RemoteServiceInput(input.getServiceId()));
			RemoteAppInfoOutput appinfo = response.getResult();
			if (appinfo == null) {
				throw new ValidationException("该应用未在配置中心注册");
			}
			Query query = new Query(SmsAppInfo.class);
			AuditUtils.filterDelete(query);
			query.eq("serviceId", input.getServiceId());
			SmsAppInfo first = appRepo.selectFirst(query.builderSection());
			if (first != null) {
				if (! first.getServiceId().equals(appInfo.getServiceId())) {
					throw new ValidationException(
							String.format("serviceId为 [%s] 的应用记录已经存在", input.getServiceId()));
				}
			}
		}
		AutoMapUtils.map(updateInput, appInfo);
		appInfo.updateAuditing();
		appRepo.update(appInfo);
		return AutoMapUtils.mapTo(SmsAppInfoOutput.class, appInfo);
	}

	@Override
	@Transactional(rollbackFor = DataRollbackException.class)
	public void delete(DefaultPrimaryKeyInput input) {
		SmsAppInfo appInfo = checkIsExistEntityByPrimaryId(input.getId());
		if (appInfo.getStatus() == ServiceConsts.Status.STATUS_RELEASE) {
			throw new ValidationException("发布状态的应用不能删除");
		}
		ISpecifyUpdateSection section = AuditUtils.softDeleteById(SmsAppInfo.class, input.getId());
		appRepo.updateBySpecify(section);
		// 删除该应用下的app_template,
		SpecifyUpdate update = new SpecifyUpdate(SmsAppTemplate.class);
		update.set("isDelete", true).set("gmtDelete", new Date()).eq("appId", input.getId());
		appTemplateRepo.updateBySpecify(update.builderSection());
		// 删除该应用下的, app_template_platform
		appTemplatePlatformRepo.deleteByAppId(appInfo.getId());
	}

	@Override
	public SmsAppInfoOutput get(DefaultPrimaryKeyInput input) {
		SmsAppInfo appInfo = checkIsExistEntityByPrimaryId(input.getId());
		return AutoMapUtils.mapTo(SmsAppInfoOutput.class, appInfo);
	}

	@Override
	protected ISmsAppInfoRepository getRepository() {
		return appRepo;
	}

	@Override
	protected Class<SmsAppInfo> getEntityClass() {
		return SmsAppInfo.class;
	}

	@Override
	public void release(DefaultPrimaryKeyInput input) {
		SmsAppInfo appInfo = checkIsExistEntityByPrimaryId(input.getId());
		if (appInfo.getStatus() == ServiceConsts.Status.STATUS_RELEASE) {
			throw new ValidationException(String.format("应用信息表中主键ID为 [%s] 的记录已发布", input.getId()));
		}
		appInfo.updateAuditing();
		appInfo.setStatus(ServiceConsts.Status.STATUS_RELEASE);
		appRepo.update(appInfo);
	}

	@Override
	@Transactional(rollbackFor = DataRollbackException.class)
	public void disable(DefaultPrimaryKeyInput input) {
		SmsAppInfo appInfo = checkIsExistEntityByPrimaryId(input.getId());
		if (appInfo.getStatus() == ServiceConsts.Status.STATUS_DISABLE) {
			throw new ValidationException(String.format("应用信息表中主键ID为 [%s] 的记录已停用", input.getId()));
		}
		appInfo.updateAuditing();
		appInfo.setStatus(ServiceConsts.Status.STATUS_DISABLE);
		appRepo.update(appInfo);
		// 停用应用，该应用下的应用模板也要停用
		SpecifyUpdate update = new SpecifyUpdate(SmsAppTemplate.class);
		update.set("status", ServiceConsts.Status.STATUS_DISABLE).set("gmtModified", new Date())
				.eq("appId", appInfo.getId()).eq("isDelete", false);
		appTemplateRepo.updateBySpecify(update.builderSection());

		// 刷新redis缓存
		cacheService.removeSendTemplate(appInfo.getServiceId());
	}

	@Override
	public PageQueryResult<SmsAppInfoOutput> pageQuery(PageQueryInput input) {
		Query query = new Query(SmsAppInfo.class);
		List<QueryCriteriaItemInput> criterias = input.getCriterias();
		if (criterias != null && criterias.size() > 0) {
			query.criteria(criterias);
		}
		Integer maxValue = getPageMaxValue();
		if (input.getPageSize() > maxValue) {
			input.setPageSize(maxValue);
		}
		query.eq("isDelete", false);
		IQuerySection section = query.builderSection();
		int count = appRepo.countByWhere(section);
		PageQueryResult<SmsAppInfoOutput> result = new PageQueryResult<SmsAppInfoOutput>(input.getCurrentPage(),
				input.getPageSize(), count);
		if (count > 0) {
			query.page(result.getCurrentPage(), result.getPageSize());
			List<SmsAppInfo> selectList = appRepo.selectList(query.builderSection());
			result.setItems(AutoMapUtils.mapList(selectList, SmsAppInfoOutput.class));
		}
		return result;
	}

}
